"""
TTS系统快速启动示例
包含解决音频文件下载问题的直接访问方法
"""
import os
import asyncio
import aiohttp
import json
from typing import Dict, Any, Optional
import uuid
from datetime import datetime
import time
import shutil

# 静态文件服务
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading

# 基础配置
SERVER_URL = "http://localhost:8021"
API_PREFIX = "/api/v1"
OUTPUT_DIR = "output"

class StaticFileServer:
    """简单的静态文件服务器"""
    def __init__(self, directory: str, port: int = 8022):
        self.directory = directory
        self.port = port
        self.httpd = None
        self.server_thread = None
        
    def start(self):
        """启动静态文件服务器"""
        os.chdir(self.directory)
        handler = SimpleHTTPRequestHandler
        self.httpd = HTTPServer(("", self.port), handler)
        
        print(f"启动静态文件服务器在端口 {self.port}...")
        self.server_thread = threading.Thread(target=self.httpd.serve_forever)
        self.server_thread.daemon = True
        self.server_thread.start()
        print(f"静态文件服务器运行中: http://localhost:{self.port}")
        
    def stop(self):
        """停止服务器"""
        if self.httpd:
            print("停止静态文件服务器...")
            self.httpd.shutdown()
            self.server_thread.join()
            print("静态文件服务器已停止")


class TTSClient:
    """TTS API客户端"""
    
    def __init__(self, base_url: str = SERVER_URL):
        """初始化客户端"""
        self.base_url = base_url
        self.api_prefix = API_PREFIX
    
    async def synthesize_text(self, text: str, voice_id: Optional[str] = None, 
                        format: str = "wav") -> Dict[str, Any]:
        """合成语音"""
        url = f"{self.base_url}{self.api_prefix}/tts/synthesize"
        
        payload = {
            "text": text,
            "format": format
        }
        
        if voice_id:
            payload["voice_id"] = voice_id
        
        try:
            async with aiohttp.ClientSession() as session:
                async with session.post(url, json=payload) as response:
                    if response.status == 200:
                        result = await response.json()
                        
                        # 正确访问字段
                        if result.get("success"):
                            print(f"合成成功: {result.get('message')}")
                            print(f"音频URL: {result.get('audio_url')}")
                            print(f"音频时长: {result.get('duration')} 秒")
                            print(f"音频格式: {result.get('format')}")
                            
                            # 返回结果
                            return result
                        else:
                            print(f"合成失败: {result.get('message')}")
                            return result
                    else:
                        print(f"请求失败: {response.status}")
                        return {"success": False, "message": f"HTTP错误: {response.status}"}
                
        except Exception as e:
            print(f"合成请求错误: {e}")
            return {"success": False, "message": f"请求错误: {str(e)}"}
    
    async def get_available_voices(self) -> list:
        """获取可用语音列表"""
        url = f"{self.base_url}{self.api_prefix}/tts/voices"
        
        try:
            async with aiohttp.ClientSession() as session:
                async with session.get(url) as response:
                    if response.status == 200:
                        return await response.json()
                    else:
                        print(f"获取语音列表失败: {response.status}")
                        return []
        except Exception as e:
            print(f"获取语音列表失败: {e}")
            return []


async def direct_file_access(audio_url: str, output_path: str, max_retries: int = 10) -> bool:
    """直接从文件系统访问音频文件，带重试机制"""
    # 从URL中提取文件名，不依赖URL路径格式
    filename = os.path.basename(audio_url)
    print(f"尝试访问文件: {filename}")
    
    # 构建源文件路径
    src_path = os.path.join("data/cache/audio", filename)
    
    # 尝试多次查找文件（可能存在写入延迟）
    for attempt in range(1, max_retries + 1):
        try:
            # 如果文件存在，直接复制
            if os.path.exists(src_path):
                print(f"找到音频文件: {src_path}")
                # 确保输出目录存在
                os.makedirs(os.path.dirname(output_path), exist_ok=True)
                # 复制文件
                shutil.copy2(src_path, output_path)
                print(f"已将音频文件复制到: {output_path}")
                return True
            else:
                print(f"尝试 {attempt}/{max_retries}: 文件不存在，等待文件写入完成...")
                
                # 如果有其他音频文件可用，直接使用最新的一个
                if attempt == max_retries // 2:
                    print("查找备选音频文件...")
                    if os.path.exists("data/cache/audio"):
                        files = os.listdir("data/cache/audio")
                        wav_files = [f for f in files if f.endswith('.wav')]
                        if wav_files:
                            # 按修改时间排序，选择最新的文件
                            newest_file = max(wav_files, key=lambda f: os.path.getmtime(os.path.join("data/cache/audio", f)))
                            print(f"使用最新的音频文件: {newest_file}")
                            alt_src_path = os.path.join("data/cache/audio", newest_file)
                            shutil.copy2(alt_src_path, output_path)
                            print(f"已将音频文件复制到: {output_path}")
                            return True
                
                # 等待一段时间后重试
                await asyncio.sleep(1)
        except Exception as e:
            print(f"访问音频文件失败 (尝试 {attempt}/{max_retries}): {e}")
            if attempt < max_retries:
                await asyncio.sleep(1)
            else:
                return False
    
    print(f"经过 {max_retries} 次尝试后仍然无法访问音频文件")
    return False


async def main():
    """主函数"""
    # 创建输出目录
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    
    # 创建静态文件服务器
    file_server = StaticFileServer(OUTPUT_DIR)
    file_server.start()
    
    try:
        # 创建TTS客户端
        client = TTSClient()
        
        # 合成文本示例
        text = "欢迎使用离线语言播放系统。这个示例展示了如何正确访问生成的音频文件。"
        result = await client.synthesize_text(text, format="wav")
        
        # 如果合成成功，复制音频文件
        if result.get("success") and result.get("audio_url"):
            # 修正API返回的URL格式 - API实际返回的是 /api/v1/audio/ 但正确路径应该是 /api/v1/tts/audio/
            audio_url = result.get("audio_url")
            print(f"原始URL: {audio_url}")
            
            # 提取音频文件名
            filename = os.path.basename(audio_url)
            print(f"文件名: {filename}")
            
            # 在这里我们忽略路径，直接使用文件名
            audio_format = result.get("format", "wav")
            
            # 生成唯一的输出文件名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            output_filename = f"tts_example_{timestamp}.{audio_format}"
            output_path = os.path.join(OUTPUT_DIR, output_filename)
            
            # 直接从文件系统访问音频文件
            if await direct_file_access(audio_url, output_path):
                print("\n成功! 你可以通过以下方式访问音频文件:")
                print(f"1. 本地文件: {output_path}")
                print(f"2. 网络访问: http://localhost:8022/{output_filename}")
                
                # 等待用户体验
                print("\n按Ctrl+C退出...")
                while True:
                    time.sleep(1)
            else:
                print("无法访问音频文件")
                
    except KeyboardInterrupt:
        print("\n用户中断，退出中...")
    finally:
        # 停止文件服务器
        file_server.stop()


if __name__ == "__main__":
    asyncio.run(main())